<template>
  <div class="city-selector-main">
    <el-popover
      v-model="show"
      placement="bottom-start"
      trigger="manual"
      popper-class="city-selector"
      :popper-options="{}"
      @show="opened"
    >
      <el-input
        v-model="value.name"
        :placeholder="placeholder"
        :class="`selected-input ${show ? 'focus' : ''}`"
        readonly
        clearable
        @focus="show = true"
        slot="reference"
      >
        <div slot="suffix">
          <i v-show="show" class="el-icon-close clear" @click="clear"></i>
          <i class="el-input__icon el-icon-arrow-up"></i>
        </div>
      </el-input>
      <div ref="selectorCountent" class="city-selector-content">
        <div class="city-selector-content-top">
          <div class="city-selector-content-top-title">请选择地区</div>
          <el-radio-group
            v-if="type !== 'single'"
            v-model="regionType"
            class="city-selector-content-top-type"
          >
            <el-radio-button label="countries">国家</el-radio-button>
            <el-radio-button label="cities">城市</el-radio-button>
          </el-radio-group>
          <el-input
            placeholder="请输入关键字"
            v-model="searchTxt"
            :validate-event="false"
            clearable
            class="city-selector-content-top-search-input"
          >
            <i slot="suffix" class="el-input__icon el-icon-search"></i>
          </el-input>
        </div>
        <div class="city-selector-content-citys">
          <city-list
            ref="cityList"
            :selected.sync="selected"
            :citys="innerCitys"
            :defaultActiveTab="defaultActiveTab"
            :warning="regionType == 'cities' ? warning : ''"
            @change="show = false"
          />
        </div>
      </div>
    </el-popover>
  </div>
</template>
<script>
import CityList from "./CityList.vue";
import { treeFilter } from "../../utils";
import { filterRegion } from "../../api/region";

export default {
  name: "CitySelector",
  components: { CityList },
  props: {
    value: {
      type: Object,
      default: { code: "", name: "" },
    },
    url: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "选择城市",
    },
  },
  data() {
    return {
      show: false,
      raw: { countries: [], cities: [] },
      regionType: "countries", // 城市
      searchTxt: "",
      selected: this.value, //{ code: "", value: "" }
      warning: "仅支持选择国内市级行政区划",
      type: "",
    };
  },
  computed: {
    innerCitys() {
      return this.searchTxt
        ? treeFilter(
            this.raw[this.regionType],
            (rc) => rc.name.indexOf(this.searchTxt) != -1
          )
        : this.raw[this.regionType];
    },
    defaultActiveTab() {
      return this.innerCitys && this.innerCitys.length > 0
        ? this.innerCitys[0].code
        : "";
    },
  },
  methods: {
    async fetchData() {
      const { data } = await filterRegion(this.url);
      const dissolve = (d, key) => {
        return {
          ...d,
          name: d.label,
          code: d.value,
          key: key,
          action: d.hasOwnProperty("info") ? d.info : true,
          children: d.hasOwnProperty("children")
            ? d.children.map((c, ii) => dissolve(c, key + "-" + ii))
            : null,
        };
      };
      if (Array.isArray(data)) {
        this.type = "single";
        this.raw = {
          countries: data
            ?.filter((d) => (d.hasOwnProperty("isShow") ? d.isShow : true))
            .map((c, i) => dissolve(c, i)),
        };
      } else {
        const { countries, cities } = data;

        this.raw = {
          countries: countries?.map((c, i) => dissolve(c, i)),
          cities: cities?.map((c, i) => dissolve(c, i)),
        };
      }
    },
    search(key) {
      // this.innerCitys =
      //     this.regionType == "国家"
      //         ? treeFilter(
      //               this.rawCities,
      //               (rc) => rc.name.indexOf(this.searchTxt) != -1
      //           )
      //         : treeFilter(
      //               this.rawCountries,
      //               (rc) => rc.name.indexOf(this.searchTxt) != -1
      //           );
      let results = [];
      function _search(nodes, path) {
        for (let node of nodes) {
          let currentPath = [...path, node]; // 创建当前路径的副本并添加当前节点
          if (node.children && node.children.length > 0) {
            _search(node.children, currentPath); // 递归搜索子节点
          }
          if (node.code === key || node.name == key) {
            // 如果找到目标节点，则记录路径
            results.push(node);
          }
        }
      }
      _search(this.raw.countries, []);
      _search(this.raw.cities, []);

      return results.length > 0 ? results[0] : null;
    },
    opened() {
      this.$nextTick(() => {
        this.$refs.cityList.show();
      });
    },
    handleClickOutside(event) {
      if (
        !this.$el.contains(event.target) &&
        !this.$refs.selectorCountent.contains(event.target)
      ) {
        this.show = false;
      }
    },
    find(code) {
      return (
        this.raw.countries?.find((c) => c.code === code) ||
        this.raw.cities?.find((c) => c.code === code)
      );
    },
    clear() {
      this.selected = { code: "", name: "" };
    },
  },
  created() {
    this.fetchData();
  },
  mounted() {
    // 添加全局点击事件监听
    document.addEventListener("click", this.handleClickOutside);
  },
  beforeDestroy() {
    // 移除全局点击事件监听
    document.removeEventListener("click", this.handleClickOutside);
  },
  watch: {
    selected(nv, ov) {
      if (nv) {
        this.$emit("input", nv);
      }
    },
    value(nv, ov) {
      if (nv) {
        this.selected = nv;
      }
    },
  },
};
</script>
<style lang="scss">
.city-selector-main {
  .selected-input {
    display: flex;
    flex-direction: row;
    align-items: center;
    width: 150px;
    height: 32px;
    line-height: 32px;
    font-size: 14px;
    .el-input__suffix-inner,
    .el-input__icon {
      line-height: 30px;
      height: auto;
      transition: transform 0.3s;
      transform: rotateZ(180deg);
    }
    &.focus .el-input__icon {
      transform: rotateZ(0deg);
    }
    input {
      height: 32px;
    }
    &.focus input {
      outline: none;
      border-color: #2e57e5;
    }
  }
  .clear {
    color: #909399;
    background-color: #c0c4cc;
    font-size: 13px;
    border-radius: 50%;
    cursor: pointer;
    &:hover {
      background-color: #909399;
      color: #fff;
    }
  }
}

.city-selector {
  padding: 0;
  @keyframes height-show {
    0% {
      height: 20;
      opacity: 0.5;
    }
    100% {
      height: 400px;
      opacity: 1;
    }
  }
  &-content {
    /* 内容 */
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 0px;

    width: 720px;
    // height: 400px;
    height: 0;

    /* N9 */
    background: #ffffff;
    mix-blend-mode: normal;
    border-radius: 4px;
    animation: height-show 0.3s ease forwards;

    &-top {
      /* Header */

      box-sizing: border-box;

      /* Auto layout */
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      padding: 0px 24px;
      gap: 16px;
      isolation: isolate;

      width: 720px;
      height: 48px;

      /* N9 */
      background: #ffffff;
      /* N6 */
      border-bottom: 1px solid #e6e9f2;
      &-title {
        width: 200px;
        height: 22px;

        /* H3-16px */
        font-family: "PingFang SC";
        font-style: normal;
        font-weight: 600;
        font-size: 16px;
        line-height: 22px;
        /* identical to box height, or 138% */

        /* N1 */
        color: #1f264d;
      }
      &-type {
        flex: 1;
        text-align: center;
        .el-radio-button {
          // width: 60px;
          // height: 28px;
          padding: 2px 1px;
          background: #f3f5fa;

          .el-radio-button__inner {
            width: 60px;
            height: 28px;
            line-height: 26px;
            padding: 0;
            border: none;
            background: #f3f5fa;
          }
          .el-radio-button__orig-radio:checked + .el-radio-button__inner {
            width: 60px;
            height: 28px;
            border: none;
            background: #ffffff;
            box-shadow: 0px 0px 1px rgba(31, 38, 76, 0.24),
              0px 2px 6px rgba(31, 38, 76, 0.06),
              0px 8px 16px -2px rgba(31, 38, 76, 0.04) !important;
            border-radius: 2px;
            /* 文本 */
            font-family: "PingFang SC";
            font-style: normal;
            font-weight: 500;
            font-size: 14px;
            line-height: 26px;
            color: #2e57e6;
          }
        }
      }
      &-search-input {
        width: 200px;
        height: 32px;

        /* N9 */
        background: #ffffff;
        border-radius: 2px;
        .el-input__inner {
          height: 32px;
          line-height: 32px;
        }
        .el-input__icon {
          line-height: 32px;
        }
        .el-input__validateIcon {
          display: none;
        }
      }
    }
    &-citys {
      padding: 0px;
      width: 100%;
      height: calc(100% - 48px);
    }
  }
}
</style>
